#ifndef CC_MACRO_DLINK_H
#define CC_MACRO_DLINK_H

/**  双链表 的一些宏操作 *****/

// #ifndef CC_OFF_SET_OF
// #define CC_OFF_SET_OF(type, member) ((long)&((type *)0)->member)
// #endif

#ifndef CC_LIST_ENTRY
#define CC_LIST_ENTRY(pNode, type, member) \
    ((type *)((char *)pNode - ((long)&((type *)0)->member)))

#endif

/* typedef struct CC_DLink_Node tDLNode; // 具有很强通用型
struct CC_DLink_Node{
    struct CC_DLink_Node* pPrev; //前
    struct CC_DLink_Node* pNext; //后
}; 

*/


// DLink - 环形双链表 宏API 
//  注意 传入参数一定是单指针，多级指针（A->B->c 替代 pHEAD）引用形式会产生副作用 

#define GDLNODE_INSERT_LOOPHEAD(pHEAD,pTARGET) \
	pHEAD = pTARGET;\
	pTARGET->pPrev = pTARGET;\
	pTARGET->pNext = pTARGET;


#define GDLNODE_INSERT_BEFORE(pHEAD,pNOW,pTARGET) \
	pTARGET->pPrev = pNOW->pPrev;\
	pTARGET->pNext = pNOW;\
	if(pNOW->pPrev != NULL){\
		pNOW->pPrev->pNext = pTARGET;\
	}\
	pNOW->pPrev = pTARGET;\
	if(pHEAD == pNOW){\
		pHEAD = pTARGET;\
	}
	

// note: (pNOW)->pNext->pPrev 之后会含副作用 
#define GDLNODE_INSERT_AFTER(pNOW,pTARGET) \
	(pTARGET)->pPrev = (pNOW);\
	(pTARGET)->pNext = (pNOW)->pNext;\
	if((pNOW)->pNext != NULL){\
		(pNOW)->pNext->pPrev = (pTARGET);\
	}\
	(pNOW)->pNext = (pTARGET);
	
	
#define GDLNODE_REMOVE(pHEAD,pNOW) \
	if(pNOW->pPrev != NULL){\
		pNOW->pPrev->pNext=pNOW->pNext;\
	}\
	if(pNOW->pNext != NULL){\
		pNOW->pNext->pPrev=pNOW->pPrev;\
	}\
	if((pHEAD) == pNOW){\
		if( pNOW->pNext == pNOW){\
			(pHEAD) = NULL;\
		}\
		else{\
			(pHEAD) = pNOW->pNext;\
		}\
	}\
	pNOW->pPrev=NULL;\
	pNOW->pNext=NULL;



#if 1 // ITERATOR  // 链表的 “指针迭代函数” 这个概念的引申十分有用！！ 

// GDLINK_ITERATOR_LOOP(POBJ) GDLINK_ITERATOR_DOWN(POBJ->pHead,LAST_Node)
#define GDLINK_ITERATOR_DOWN(END_NODE,LAST_NODE) \
	ptmp = LAST_NODE->pNext;\
	if( (ptmp == END_NODE) || (ptmp == NULL)){\
		ptmp = NULL;\
		break;\
	}

	
#define GDLINK_ITERATOR_UP(END_NODE,LAST_NODE) \
	ptmp = LAST_NODE->pPrev;\
	if( (ptmp == END_NODE) || (ptmp == NULL)){\
		ptmp=NULL;\
		break;\
	}
	
#endif 

#endif 


